package com.deer.wms.ware.task.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.deer.wms.base.system.model.*;
import com.deer.wms.base.system.model.Item.ItemErpBO;
import com.deer.wms.base.system.model.Item.ItemInfo;
import com.deer.wms.base.system.service.ItemInfoService;
import com.deer.wms.busine.tactic.model.RouteTactic;
import com.deer.wms.busine.tactic.model.RouteTacticCriteria;
import com.deer.wms.busine.tactic.service.RouteTacticService;
import com.deer.wms.intercept.common.data.CurrentUser;
import com.deer.wms.inventory.constant.InventoryConstant;
import com.deer.wms.inventory.model.Inventory.InventoryTransact;
import com.deer.wms.inventory.service.InventoryService;
import com.deer.wms.inventory.service.InventoryTransactService;
import com.deer.wms.project.root.core.result.CommonCode;
import com.deer.wms.project.root.exception.ServiceException;
import com.deer.wms.project.root.service.SuperServiceImpl;
import com.deer.wms.project.root.util.BeanUtils;
import com.deer.wms.project.root.util.DateUtils;
import com.deer.wms.project.root.util.HttpClient;
import com.deer.wms.review.manage.model.BillRecord;
import com.deer.wms.review.manage.service.BillRecordService;
import com.deer.wms.review.manage.service.CaseMasterService;
import com.deer.wms.system.manage.model.organization.Organization;
import com.deer.wms.system.manage.model.ware.WareInfo;
import com.deer.wms.system.manage.service.OrganizationService;
import com.deer.wms.system.manage.service.ValidatorService;
import com.deer.wms.system.manage.service.WareInfoService;
import com.deer.wms.ware.task.constant.WareTaskConstant;
import com.deer.wms.ware.task.dao.SoDetailMapper;
import com.deer.wms.ware.task.dao.SoMasterMapper;
import com.deer.wms.ware.task.model.SO.CreateSo.CreateSo;
import com.deer.wms.ware.task.model.SO.CreateSo.CreateSoDeliveryAddress;
import com.deer.wms.ware.task.model.SO.CreateSo.CreateSoShippingAddress;
import com.deer.wms.ware.task.model.SO.CreateSo.CreateSoSkuDetail;
import com.deer.wms.ware.task.model.SO.*;
import com.deer.wms.ware.task.model.pickTask.PickTask;
import com.deer.wms.ware.task.service.*;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by guo on 2020/02/02.
 */
@Service
@Transactional
public class SoMasterServiceImpl extends SuperServiceImpl<SoMasterMapper, SoMaster> implements SoMasterService {

    @Autowired
    private SoMasterMapper soMasterMapper;

    @Autowired
    private ValidatorService validatorService;

    @Autowired
    private SoMasterService soMasterService;

    @Autowired
    private SoDetailService soDetailService;

    @Autowired
    private CaseMasterService caseMasterService;

    @Autowired
    private SoMasterFileService soMasterFileService;

    @Autowired
    private SoDetailFileService soDetailFileService;
    @Autowired
    private RouteTacticService routeTacticService;

    @Autowired
    private BillRecordService billRecordService;
    @Autowired
    private InventoryService inventoryService;
    @Autowired
    private InventoryTransactService inventoryTransactService;
    @Autowired
    private PickTaskService pickTaskService;
    @Autowired
    private SoDetailMapper soDetailMapper;

    @Override
    public List<SoMasterDto> findList(SoMasterCriteria criteria) {
        return soMasterMapper.findList(criteria);
    }

    @Override
    public List<SoMasterDto> findByWaveId(Integer id,Integer wareId) {
        return soMasterMapper.findByWaveId(id,wareId);
    }


    @Override
    public SoMasterDto getSeedingByItemCode(String  itemCode, Integer wareId, Integer waveMasterId) {
        List<SoMasterDto> list = soMasterMapper.getSeedingByItemCode(itemCode,wareId,waveMasterId);
        if(list.size()>0){

            return list.get(0);
        }else {
            return null;
        }
    }


    @Override
    public void deleteByBillNo(String billNo) {
        soMasterMapper.deleteByBillNo(billNo);
    }


    @Override
    public void createSoMaster(SoData soData, CurrentUser currentUser) {
        /**
         *  新建SO单据
         */
        SoMaster soMaster = soData.getSoMaster();
        String tableName = "so_master";
        Integer nextId = validatorService.getNextId(tableName);

        String billNo = "SO" + "-" + nextId;
        Integer createUserId = currentUser.getUserId();
        String createUserName = currentUser.getUserName();
        String createTime = DateUtils.getNowDateTimeString();

        if (soData.getBillSource() == 1 || soData.getBillSource() == 3 || soData.getBillSource() == 4) {
            //状态    2-等待审核(初始化)  1-审核通过  0-审核中  -1-审核退回
            Integer state = 1;

            if (soData.getInsertType() == -2) {
                //草稿
                state = 1;
            } else if (soData.getInsertType() == 0) {
                //正式提交
                String billNo1 = soData.getSoMaster().getBillNo();
                //通过草稿提交，则需要先把草稿删掉
                if (billNo1 != null) {
                    soMasterService.deleteByBillNo(billNo1);
                }
                /**
                 * 添加审核流
                 */
                //        -1不通过  0-流转中 1-已通过
                state = caseMasterService.createCase(billNo, 3, currentUser.getUserId(), soMaster.getWareId(), soMaster.getOrganizationId());
            }

            soMaster.setCreateUserId(createUserId);
            soMaster.setCreateUserName(createUserName);
            soMaster.setCreateTime(createTime);
            soMaster.setBillNo(billNo);
            soMaster.setCaseState(state);
            soMaster.setInsertType(soData.getInsertType());
            soMaster.setBillSource(soData.getBillSource());
            soMaster.setSoStructure(soData.getSoDetails().size());
            soMasterService.save(soMaster);


            List<SoDetail> soDetails = soData.getSoDetails();
            for (int i = 0; i < soDetails.size(); i++) {
                String detailNo = billNo + "-" + (i + 1);
                SoDetail soDetail = soDetails.get(i);
                soDetail.setBillNo(billNo);
                soDetail.setDetailNo(detailNo);
                soDetail.setState(0);
                soDetailService.save(soDetail);
            }
        }
    }

    @Override
    public void createFile(String billNo,CurrentUser currentUser){
        SoMaster soMaster = this.findBy("bill_no",billNo);
        //状态为 ASN完成状态
        Integer fileUserId = currentUser.getUserId();
        String fileUserName = currentUser.getUserName();
        String fileTime = DateUtils.getNowDateTimeString();
        if(soMaster.getState() !=10){
            throw new ServiceException(CommonCode.SO_FILE_ERROR);
        }
        BillRecord billRecord =new BillRecord();
        billRecord.setBillNo(billNo);
        billRecord.setRecordType(26);//SO归档
        billRecord.setCreateTime(fileTime);
        billRecord.setCreateUserId(fileUserId);
        billRecord.setCreateUserName(fileUserName);
        billRecordService.createBillRecord(billRecord,currentUser);

        SoMasterFile soMasterFile = new SoMasterFile();
        BeanUtils.copyProperties(soMaster, soMasterFile);

        soMasterFile.setFileUserId(fileUserId);
        soMasterFile.setFileUserName(fileUserName);
        soMasterFile.setFileTime(fileTime);
        soMasterFileService.save(soMasterFile);

        List<SoDetail> soDetails = soDetailService.findByBillNo(billNo);

        for(int i=0;i<soDetails.size();i++){

            SoDetail soDetail = soDetails.get(i);
            SoDetailFile soDetailFile = new SoDetailFile();
            BeanUtils.copyProperties(soDetail, soDetailFile);

            soDetailFileService.save(soDetailFile);


        }
        soMasterService.deleteByBillNo(billNo);
        BillRecord billRecord1 = billRecordService.findByBillNoAndType(billNo,26);//SO归档
        billRecord1.setModifyUserId(fileUserId);
        billRecord1.setModifyUserName(fileUserName);
        billRecord1.setModifyTime(DateUtils.getNowDateTimeString());
        billRecordService.updateById(billRecord1);
    }

    @Override
    public SoMaster findBy(String fileName, String value) {
        QueryWrapper<SoMaster> qw = new QueryWrapper<>();
        return this.getOne(qw.eq(fileName, value));
    }

    @Override
    public void sendOut(SoMaster soMaster, CurrentUser currentUser) {
        //Step1.生成库存事务
        List<PickTask> pickTasks = pickTaskService.findBySoMasterId(soMaster.getSoMasterId());
        for (PickTask pickTask : pickTasks) {
            toStockRequest(pickTask, currentUser);
        }

        //Step2.扣减库存
        inventoryService.sendOut(soMaster.getBillNo(), soMaster.getWareId());

        //Step3.回写单据状态
        soMaster.setState(WareTaskConstant.SO_STATE_OUTED);
        soMaster.setOutTime(DateUtils.getNowDateTimeString());
        soMaster.setOutUserId(currentUser.getUserId());
        soMaster.setOutUserName(currentUser.getUserName());
//        soMaster.setWeight(weight);
        soMasterService.updateById(soMaster);
        List<SoDetail> soDetails = soDetailService.findByBillNo(soMaster.getBillNo());
        for (SoDetail soDetail : soDetails) {
            soDetail.setDeliveryQuantity(soDetail.getOrderQuantity());
            soDetail.setState(WareTaskConstant.SO_DETAIL_STATE_ALL_SEND);
        }
        soDetailService.updateBatchById(soDetails);

        for (PickTask pickTask : pickTasks) {
            pickTask.setSeededQuantity(pickTask.getPickQuantity());
            pickTask.setState(WareTaskConstant.PICK_STATE_OUTED);
        }
        pickTaskService.updateBatchById(pickTasks);
    }

    private InventoryTransact toStockRequest(PickTask pickTask, CurrentUser currentUser) {
        InventoryTransact inventoryTransact = new InventoryTransact();
        //Step1.准备数据
        //仓库
        inventoryTransact.setWareId(pickTask.getWareId());
        inventoryTransact.setWareName(pickTask.getWareName());
        //货主
        inventoryTransact.setToOrganizationId(pickTask.getOrganizationId());
        inventoryTransact.setToOrganizationName(pickTask.getOrganizationName());
        //库位
        inventoryTransact.setFromCellCode(pickTask.getCellCode());
        //容器
        inventoryTransact.setFromBoxCode(pickTask.getBoxCode());
        //物料
        inventoryTransact.setItemCode(pickTask.getItemCode());
        inventoryTransact.setItemName(pickTask.getItemName());
        inventoryTransact.setImgUrl(pickTask.getImgUrl());
        //批次
        inventoryTransact.setFromBatchId(pickTask.getBatchId());
        inventoryTransact.setFromBatchName(pickTask.getBatchName());
        //数量
        inventoryTransact.setFromQuantity(pickTask.getPickQuantity());
        //包装 转换率
        inventoryTransact.setFromPackDetailId(pickTask.getPackDetailId());
        inventoryTransact.setFromPackDescribe(pickTask.getPackDescribe());
        //创建人 时间
        inventoryTransact.setCreateUserId(currentUser.getUserId());
        inventoryTransact.setCreateUserName(currentUser.getUserName());
        inventoryTransact.setCreateTime(DateUtil.now());
        //事务类型
        inventoryTransact.setTransactType(InventoryConstant.INVENTORY_TYPE_OUT);
        //来源单据号
        inventoryTransact.setBillNo(pickTask.getPickTaskCode());

        //Step2.保存，返回
        inventoryTransactService.save(inventoryTransact);
        return inventoryTransact;
    }

    @Override
    public List<SoMaster> findSoGroupInfo(SoMasterCriteria criteria) {
        return soMasterMapper.findSoGroupInfo(criteria);
    }

    @Override
    public List<SoMaster> findSoByWave(SoMasterCriteria criteria) {
        return soMasterMapper.findSoByWave(criteria);
    }

    @Override
    public Integer findCountByWaveIdAndState(Integer waveMasterId,Integer state) {
        return soMasterMapper.findCountByWaveIdAndState(waveMasterId,state);
    }


    @Override
    public List<SoMaster> findCanTongBu() {
        return soMasterMapper.findCanTongBu();
    }

    @Override
//    public void setCarriersWithRouteTactic(Integer organizationId, Integer wareId) {
    public void setCarriersWithRouteTactic() {
        SoMasterCriteria soMasterCriteria = new SoMasterCriteria();
//        soMasterCriteria.setOrganizationId(organizationId);
//        soMasterCriteria.setWareId(wareId);
        List<SoMasterDto> soMasters = soMasterMapper.findThatNoCarrier(soMasterCriteria);
        RouteTacticCriteria criteria = new RouteTacticCriteria();
//        criteria.setOrganizationId(organizationId);
//        criteria.setWareId(wareId);
        criteria.setState(1);
        List<RouteTactic> routeTactics = routeTacticService.findList(criteria);
        if (routeTactics.size() == 0) {
            throw new ServiceException(CommonCode.NO_ROUTE_TACTIC);
        }

        for (SoMasterDto soMaster : soMasters) {
            Double weight = soMaster.getWeight();
            Double size = soMaster.getSize();
            tacticLoop:
            for (RouteTactic routeTactic : routeTactics) {
                Double maxWeight = routeTactic.getMaxWeight();
                Double minWeight = routeTactic.getMinWeight();
                Double maxSize = routeTactic.getMaxSize();
                Double minSize = routeTactic.getMinSize();
                if (weight > minWeight && weight < maxWeight && size > minSize && size < maxSize) {
                    soMaster.setCarrierId(routeTactic.getCarrierId());
                    soMaster.setCarrierName(routeTactic.getCarrierName());
                    soMasterService.updateById(soMaster);
                    break tacticLoop;
                }
            }
        }
    }

    @Override
    public List<PdaSearchSoData> pdaSearchSo(String trackCode) {
        return soMasterMapper.pdaSearchSo(trackCode);
    }

    @Override
    public SoMasterYdyp getYdyp(String itemCode, Integer wareId,Integer waveId) {
        return soMasterMapper.getYdyp(itemCode,wareId,waveId);
    }

    @Override
    public SoMasterYdyp getYdyp2(String itemCode, Integer wareId,Integer waveId) {
        return soMasterMapper.getYdyp2(itemCode,wareId,waveId);
    }


    @Autowired
    private WareInfoService wareInfoService;
    @Autowired
    private ItemInfoService itemInfoService;
    @Autowired
    private OrganizationService organizationService;

    @Override
    public void createSO(CreateSo createSo, CurrentUser currentUser) {
        SoMaster soMaster =  soMaster= this.findBy("bill_no",createSo.getBillNo());
        if(soMaster!=null){
            throw  new ServiceException(CommonCode.BILL_NO, "");
        }
        soMaster = new SoMaster();
        if(createSo.getWareCode()==null){
            throw  new ServiceException(CommonCode.WARE_NULL, "");
        }
        if(createSo.getOrgCode()==null){
            throw  new ServiceException(CommonCode.ORG_NULL, "");
        }

        String billNo = createSo.getBillNo();
        Integer createUserId = currentUser.getUserId();
        String createUserName = currentUser.getUserName();
        String createTime = DateUtils.getNowDateTimeString();
        String wareCode = createSo.getWareCode();
        String orgCode = createSo.getOrgCode();
        WareInfo wareInfo = wareInfoService.getOneByField("ware_code",wareCode);
        Organization organization = organizationService.findBy("organizationCode",orgCode);

        if(createSo.getOrderTime()==null || createSo.getOrderTime().equals("")){
            throw  new ServiceException(CommonCode.SERVER_INERNAL_ERROR, "下单时间不得为空");
        }

        if(wareInfo==null){
            throw  new ServiceException(CommonCode.WARE_NULL, "");
        }
        if(organization==null){
            throw  new ServiceException(CommonCode.ORG_NULL, "");
        }
        Integer state = 2;
       // state = caseMasterService.createCase(billNo, 2, currentUser.getUserId(), wareInfo.getWareId(),organization.getOrganizationId());

        soMaster.setState(state);
        soMaster.setBillNo(billNo);
        soMaster.setCreateTime(createTime);
        soMaster.setCreateUserId(createUserId);
        soMaster.setCreateUserName(createUserName);
        soMaster.setWareId(wareInfo.getWareId());
        soMaster.setWareName(wareInfo.getWareName());
        soMaster.setWareId(wareInfo.getWareId());
        soMaster.setWareCode(wareInfo.getWareCode());
        soMaster.setOrganizationCode(organization.getOrganizationCode());
        soMaster.setOrganizationName(organization.getOrganizationName());
        soMaster.setOrganizationId(organization.getOrganizationId());
        soMaster.setAllotBillNo(createSo.getBillNo());
        soMaster.setShipCode(createSo.getShipCode());
        soMaster.setShipBillCode(createSo.getShipBillCode());
        soMaster.setExpressBillUrl(createSo.getExpressBillUrl());
        soMaster.setInsertType(4);
        soMaster.setOrderTime(createSo.getOrderTime());

        CreateSoShippingAddress shippingAddress = createSo.getShippingAddress();
        soMaster.setShipLinkMan(shippingAddress.getLinkMan());
        soMaster.setShipLinkPhone(shippingAddress.getLinkPhone());
        soMaster.setShipCity(shippingAddress.getCity());
        soMaster.setShipCountry(shippingAddress.getCountry());
        soMaster.setShipProvince(shippingAddress.getProvince());
        soMaster.setShipArea(shippingAddress.getArea());
        soMaster.setShipDetailAddress(shippingAddress.getDetailAddress());

        CreateSoDeliveryAddress deliveryAddress = createSo.getDeliveryAddress();
        soMaster.setLinkMan(deliveryAddress.getLinkMan());
        soMaster.setLinkPhone(deliveryAddress.getLinkPhone());
        soMaster.setProvince(deliveryAddress.getProvince());
        soMaster.setCity(deliveryAddress.getCity());
        soMaster.setCountry(deliveryAddress.getCountry());
        soMaster.setArea(deliveryAddress.getArea());
        soMaster.setDetailAddress(deliveryAddress.getDetailAddress());
        soMaster.setCountry(deliveryAddress.getCountry());



        soMaster.setLastMileDestination(createSo.getLastMileDestination());
        soMaster.setLastMileLineCode(createSo.getLastMileLineCode());
        soMaster.setLastMileSortingCode(createSo.getLastMileSortingCode());
        soMaster.setSoUdfHs1(createSo.getExt1());
        soMaster.setSoUdfHs2(createSo.getExt2());
        soMaster.setSoUdfHs3(createSo.getExt3());
        soMaster.setSoStructure(createSo.getSoSkuDetails().size());
        soMaster.setTotalPrice(createSo.getCodValue());
        soMaster.setTradeNo(createSo.getTradeNo());
        soMaster.setShop(createSo.getShop());
        soMasterService.save(soMaster);



        List<CreateSoSkuDetail> asnskuDetails = createSo.getSoSkuDetails();
        for(int i = 0;i<asnskuDetails.size();i++){
            CreateSoSkuDetail createSoSkuDetail = asnskuDetails.get(i);

            SoDetail soDetail = new SoDetail();
            soDetail.setBillNo(soMaster.getBillNo());
            soDetail.setDetailNo(soMaster.getBillNo()+(i+1));
            soDetail.setItemCode(createSoSkuDetail.getSkuCode());

            if(createSoSkuDetail.getSkuCode()==null || createSoSkuDetail.getSkuCode().trim().equals("")){
                throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR,"SKU无效");
            }
            ItemInfo itemInfo = itemInfoService.findBy("item_code",createSoSkuDetail.getSkuCode());
            if(itemInfo==null){
                itemInfo = new ItemInfo();
                itemInfo.setImgUrl(createSoSkuDetail.getImgUrl());
                itemInfo.setItemCode(createSoSkuDetail.getSkuCode());
                itemInfo.setItemName(createSoSkuDetail.getSkuName());
                itemInfo.setPackCode("sys_pack");
                itemInfoService.save(itemInfo);
            }
            soDetail.setItemName(itemInfo.getItemName());
            soDetail.setSpec(itemInfo.getSpec());
            soDetail.setModel(itemInfo.getModel());
            soDetail.setImgUrl(itemInfo.getImgUrl());
            soDetail.setPackDetailId(166);
            soDetail.setTransRatio(1.0);
            soDetail.setPackDescribe("each");
            soDetail.setOrderQuantity(createSoSkuDetail.getQuantity());
            soDetailService.save(soDetail);
        }
    }

    @Override
    public Integer getMaxPriority() {
        return soMasterMapper.getMaxPriority();
    }

    @Override
    public void updatePriority(Integer soMasterId, Integer priority) {
        soMasterMapper.updatePriority(soMasterId,priority);
    }

    @Override
    public String saveBillOutInfo() {

        try {
            //请求token
            System.out.println("请求token");
            MultiValueMap<String, String> stringMultiValueMap = new LinkedMultiValueMap<>();
            stringMultiValueMap.add("client_id", "KingdeeK3_Rggytest_EpichustClient");
            stringMultiValueMap.add("client_secret", "TekE%dAISMCvwk7V");
            stringMultiValueMap.add("grant_type", "client_credentials");
            String tokenUrl = "https://identityserver:44310/connect/token";
            String clientRg = HttpClient.clientRg(tokenUrl, HttpMethod.POST, stringMultiValueMap);
            JSONObject jsonObject = JSONObject.parseObject(clientRg);
            String token = jsonObject.getString("access_token");
            System.out.println("token" + token);

            if(token != null){

                    Map<String, String> map1 = new HashMap<>();
                    map1.put("dateFrom","2022-04-01");

                    //调用erp接口获取数据
                    CloseableHttpClient client = HttpClients.createDefault();
                    URIBuilder uriBuilder = new URIBuilder("http://10.18.3.10:30001/api/Epichust/GetAllIMOutSourceBills");
                    HttpPost post = new HttpPost(uriBuilder.build());
                    StringEntity myEntity = new StringEntity(JSON.toJSONString(map1), "UTF-8");// 构造请求数据
                    post.setHeader("Content-Type", "application/json");
                    post.addHeader("Authorization", "Bearer " + token);
                    post.setEntity(myEntity);// 设置请求体
                    String responseContent = null; // 响应内容
                    CloseableHttpResponse response = null;
                    try {
                        response = client.execute(post);
                        HttpEntity entity = response.getEntity();
                        if (response.getStatusLine().getStatusCode() == 200) {
                            String content = EntityUtils.toString(entity, "UTF-8");
                            List<BillOutBO> po = (List<BillOutBO>) JSON
                                    .parseArray(content, BillOutBO.class);
                            if(po.size() != 0){
                                for(BillOutBO bo : po){
                                    //先判断抓取的数据在数据库中是否存在
                                    QueryWrapper<SoMaster> qw = Wrappers.query();
                                    Map<String, Object> map = new HashMap<>();
                                    map.put("bill_no", bo.getBillNo());
                                    map.put("organization_id", bo.getBillTypeId());
                                    SoMaster info = soMasterMapper.selectOne(qw.allEq(map, false));
                                    if(info == null){
                                        SoMaster soMaster = new SoMaster();
                                        soMaster.setCreateTime(DateUtils.getNowDateTimeString());
                                        soMaster.setOrganizationId(bo.getId());//主键
                                        soMaster.setWareId(285);
                                        soMaster.setCreateUserName(bo.getBillTypeId().toString());
                                        soMaster.setWareCode(bo.getBillTypeName());//单据类型
                                        soMaster.setBillNo(bo.getBillNo());//单据编号
                                        soMaster.setOutUserName(bo.getBillDate());//单据日期
                                        soMaster.setCarrierId(bo.getBillStatus());//工业单据状态
                                        soMaster.setOrganizationCode(bo.getBillClosed() == null || bo.getBillClosed() == false ? "0" : "1");//关闭状态
                                        soMaster.setCreateUserId(bo.getSupplierId());//供应商ID
                                        soMaster.setSoUdfHs2(bo.getSupplierName());//供应商名称
                                        soMaster.setCustomerId(bo.getCustomerId());//客户ID
                                        soMaster.setCustomerName(bo.getCustomerName());//客户名称
                                        soMaster.setOutUserId(bo.getDeptId());//部门ID
                                        soMaster.setCarrierName(bo.getDeptName());//部门名称
                                        soMaster.setMemo(bo.getRemark());//备注
                                        soMasterMapper.insert(soMaster);
                                        System.out.println("保存了主表信息");
                                        List<BillOutDetailBO> billOutDetailBOS = bo.getDetails();
                                        for(BillOutDetailBO billOutDetailBO :billOutDetailBOS){
                                            SoDetail soDetail = new SoDetail();
                                            soDetail.setBillNo(soMaster.getBillNo());
                                            soDetail.setPackDetailId(billOutDetailBO.getRowIndex());//行号
                                            soDetail.setAllotPackDetailId(billOutDetailBO.getItemId());//物料ID
                                            soDetail.setItemCode(billOutDetailBO.getItemNumber());//物料编码
                                            soDetail.setItemName(billOutDetailBO.getItemName());//物料名称
                                            soDetail.setSpec(billOutDetailBO.getItemModel());//规格型号
                                            soDetail.setPickPackDetailId(billOutDetailBO.getAuxPropClassId());//辅助属性类别ID
                                            soDetail.setDeliveryPackDetailId(billOutDetailBO.getAuxPropId());//辅助属性ID
                                            soDetail.setModel(billOutDetailBO.getAuxPropName());//辅助属性
                                            //批次管理
                                            soDetail.setPackDescribe(billOutDetailBO.getBatchManager() == null || billOutDetailBO.getBatchManager() == false ? "0" : "1");
                                            soDetail.setDetailNo(billOutDetailBO.getBatchNo());//批号
                                            soDetail.setBomSplit(billOutDetailBO.getUnitId());//基本单位ID
                                            soDetail.setSoUdfDs2(billOutDetailBO.getUnitName());//单位
                                            soDetail.setOrderQuantity(billOutDetailBO.getQty());//基本单位数量
//                                soDetail.setAllotPackDescribe(billOutDetailBO.getPlanModeId().toString());//计划模式ID
                                            soDetail.setSoUdfDs3(billOutDetailBO.getMtoNo());//计划跟踪号
                                            soDetail.setMemo(billOutDetailBO.getRemark());//备注
                                            soDetail.setPickPackDescribe(billOutDetailBO.getTargetBillTypeId().toString());//目标单据类型ID
                                            //目标单据红蓝字
                                            soDetail.setMergeNo(billOutDetailBO.getTargetBillROB() == null || billOutDetailBO.getTargetBillROB() == false ? "0" : "1");
                                            soDetail.setAllotPackDescribe(billOutDetailBO.getShelfLifeDays().toString());
                                            soDetail.setDeliveryPackDescribe(billOutDetailBO.getShelfLifeManager() == null || billOutDetailBO.getShelfLifeManager() == false ? "0" : "1");
                                            soDetail.setAllotDetailNo(billOutDetailBO.getProductionDate());
                                            soDetail.setTransRatio(1.00);
                                            soDetailMapper.insert(soDetail);
                                            System.out.println("保存了子表信息");
                                        }
                                    }
                                }
                            }


                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }  finally {
                        try {
                            if (response != null)
                                response.close();

                        } catch (IOException e) {
                            e.printStackTrace();
                        } finally {
                            try {
                                if (client != null)
                                    client.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
            }

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

        return null;
    }

    @Override
    public String outbillToErp() {

        try {
            //请求token
            MultiValueMap<String, String> stringMultiValueMap = new LinkedMultiValueMap<>();
            stringMultiValueMap.add("client_id", "KingdeeK3_Rggytest_EpichustClient");
            stringMultiValueMap.add("client_secret", "TekE%dAISMCvwk7V");
            stringMultiValueMap.add("grant_type", "client_credentials");
            String tokenUrl = "https://identityserver:44310/connect/token";
            String clientRg = HttpClient.clientRg(tokenUrl, HttpMethod.POST, stringMultiValueMap);
            JSONObject jsonObject = JSONObject.parseObject(clientRg);
            String token = jsonObject.getString("access_token");

            if(token != null){

//                QueryWrapper<AcceptRecord> qw = Wrappers.query();
//                List<AcceptRecord> acceptRecords = acceptRecordMapper.selectList(qw.eq("is_transmit", "0"));
                QueryWrapper<SoMaster> qw = Wrappers.query();
                List<SoMaster> soMasters = soMasterMapper.selectList(qw.ne("is_transmit", "1"));
                for(SoMaster soMaster : soMasters){

//                    if(asnMaster != null){
                    OrderToErpBO bo = new OrderToErpBO();
                    QueryWrapper<SoDetail> adqw = Wrappers.query();
                    List<OrderDetailBO> pd = new ArrayList<>();
                    List<SoDetail> asnDetails = soDetailMapper.selectList(adqw.eq("bill_no", soMaster.getBillNo()));
                    for(SoDetail soDetail : asnDetails){
                        OrderDetailBO db = new OrderDetailBO();
                        db.setSourceBillDetailRowIndex(soDetail.getPackDetailId());
                        db.setAuxPropId(soDetail.getDeliveryPackDetailId());
                        db.setBatchNo(soDetail.getDetailNo());
                        db.setQty(0.00);
                        db.setMtoNo(soDetail.getSoUdfDs3());
                        db.setRemark(soDetail.getMemo());
                        db.setProductionDate(soDetail.getAllotDetailNo());
                        db.setShelfLifeDays(Integer.parseInt(soDetail.getAllotPackDescribe()));
//                        db.setSourceBillId(asnMaster.getOrganizationId());
                        db.setStockPlaceId(1);

//                        bo.setBillTypeId(Integer.parseInt(asnDetail.getUpperPackDescribe()));
                        pd.add(db);
                    }
                    bo.setBillNo(soMaster.getSoMasterId().toString());
                    bo.setBillDate(new SimpleDateFormat("yyyy-MM-dd").format(new SimpleDateFormat("yyyy-MM-dd").parse(soMaster.getOutUserName())));
//                    bo.setSourceBillTypeId(soMaster.getBillType());
                    bo.setStockId(5924);
                    bo.setRemark(soMaster.getMemo());
                    bo.setDetails(pd);
                    //调用erp接口获取数据
                    CloseableHttpClient client = HttpClients.createDefault();
                    URIBuilder uriBuilder = new URIBuilder("http://10.18.3.10:30001/api/IMBill/PushIMBill");
                    HttpPost post = new HttpPost(uriBuilder.build());
                    StringEntity myEntity = new StringEntity(JSON.toJSONString(bo), "UTF-8");// 构造请求数据
                    //                httpHeaders.add("Accept", "application/json");
                    //                httpHeaders.add("Authorization", "Bearer " + token);
                    post.setHeader("Content-Type", "application/json");
                    post.addHeader("Authorization", "Bearer " + token);
                    post.setEntity(myEntity);// 设置请求体
                    String responseContent = null; // 响应内容
                    CloseableHttpResponse response = null;
                    try {
                        response = client.execute(post);
                        System.out.println("response===>" + JSON.toJSONString(response));
                        if (response.getStatusLine().getStatusCode() == 200) {
                            //                    System.out.println("sucess");
                            //修改推送到智能货柜的数据状态  acceptRecords
                            for(SoMaster ar : soMasters){
                                ar.setIsTransmit("1");
                                soMasterMapper.updateById(ar);
                            }
                        }
                        //                System.out.println("responseContent:" + responseContent);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }  finally {
                        try {
                            if (response != null)
                                response.close();

                        } catch (IOException e) {
                            e.printStackTrace();
                        } finally {
                            try {
                                if (client != null)
                                    client.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
//                }

            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return null;
    }

    @Override
    public void createSoMaster2(SoData soData, CurrentUser currentUser) {
        /**
         *  新建SO单据
         */
        SoMaster soMaster = soData.getSoMaster();
        String tableName = "so_master";
        Integer nextId = validatorService.getNextId(tableName);

        String billNo = "SO" + "-" + nextId;
        Integer createUserId = currentUser.getUserId();
        String createUserName = currentUser.getUserName();
        String createTime = DateUtils.getNowDateTimeString();

        if (soData.getBillSource() == 1 || soData.getBillSource() == 3 || soData.getBillSource() == 4) {
            //状态    2-等待审核(初始化)  1-审核通过  0-审核中  -1-审核退回
            Integer state = 1;

            if (soData.getInsertType() == -2) {
                //草稿
                state = 1;
            } else if (soData.getInsertType() == 0) {
                //正式提交
                String billNo1 = soData.getSoMaster().getBillNo();
                //通过草稿提交，则需要先把草稿删掉
                if (billNo1 != null) {
                    soMasterService.deleteByBillNo(billNo1);
                }
                /**
                 * 添加审核流
                 */
                //        -1不通过  0-流转中 1-已通过
                state = caseMasterService.createCase(billNo, 3, currentUser.getUserId(), soMaster.getWareId(), soMaster.getOrganizationId());
            }

            soMaster.setCreateUserId(createUserId);
            soMaster.setCreateUserName(createUserName);
            soMaster.setCreateTime(createTime);
            soMaster.setBillNo(billNo);
            soMaster.setCaseState(state);
            soMaster.setInsertType(soData.getInsertType());
            soMaster.setBillSource(soData.getBillSource());
            soMaster.setSoStructure(soData.getSoDetails().size());
            soMaster.setSoUdfHs1("1");//标记先发配件出库单据
            soMasterService.save(soMaster);


            List<SoDetail> soDetails = soData.getSoDetails();
            for (int i = 0; i < soDetails.size(); i++) {
                String detailNo = billNo + "-" + (i + 1);
                SoDetail soDetail = soDetails.get(i);
                soDetail.setBillNo(billNo);
                soDetail.setDetailNo(detailNo);
                soDetail.setState(0);
                soDetailService.save(soDetail);
            }
        }
    }

    @Override
    public List<SoMasterDto> findList2(SoMasterCriteria criteria) {
        return soMasterMapper.findList2(criteria);
    }

    @Override
    public void createSoMaster3(SoData soData, CurrentUser currentUser) {
        /**
         *  新建SO单据
         */
        SoMaster soMaster = soData.getSoMaster();
        String tableName = "so_master";
        Integer nextId = validatorService.getNextId(tableName);

        String billNo = "SO" + "-" + nextId;
        Integer createUserId = currentUser.getUserId();
        String createUserName = currentUser.getUserName();
        String createTime = DateUtils.getNowDateTimeString();

        if (soData.getBillSource() == 1 || soData.getBillSource() == 3 || soData.getBillSource() == 4) {
            //状态    2-等待审核(初始化)  1-审核通过  0-审核中  -1-审核退回
            Integer state = 1;

            if (soData.getInsertType() == -2) {
                //草稿
                state = 1;
            } else if (soData.getInsertType() == 0) {
                //正式提交
                String billNo1 = soData.getSoMaster().getBillNo();
                //通过草稿提交，则需要先把草稿删掉
                if (billNo1 != null) {
                    soMasterService.deleteByBillNo(billNo1);
                }
                /**
                 * 添加审核流
                 */
                //        -1不通过  0-流转中 1-已通过
                state = caseMasterService.createCase(billNo, 3, currentUser.getUserId(), soMaster.getWareId(), soMaster.getOrganizationId());
            }

            soMaster.setCreateUserId(createUserId);
            soMaster.setCreateUserName(createUserName);
            soMaster.setCreateTime(createTime);
            soMaster.setBillNo(billNo);
            soMaster.setCaseState(state);
            soMaster.setInsertType(soData.getInsertType());
            soMaster.setBillSource(soData.getBillSource());
            soMaster.setSoStructure(soData.getSoDetails().size());
            soMaster.setSoUdfHs1("2");//标记先发配件出库单据
            soMasterService.save(soMaster);


            List<SoDetail> soDetails = soData.getSoDetails();
            for (int i = 0; i < soDetails.size(); i++) {
                String detailNo = billNo + "-" + (i + 1);
                SoDetail soDetail = soDetails.get(i);
                soDetail.setBillNo(billNo);
                soDetail.setDetailNo(detailNo);
                soDetail.setState(0);
                soDetailService.save(soDetail);
            }
        }
    }

    @Override
    public List<SoMasterDto> findList3(SoMasterCriteria criteria) {
        return soMasterMapper.findList3(criteria);
    }

    public static void main(String[] args) throws Exception {

        //请求token
        System.out.println("请求token");
        MultiValueMap<String, String> stringMultiValueMap = new LinkedMultiValueMap<>();
        stringMultiValueMap.add("client_id", "KingdeeK3_Rggytest_EpichustClient");
        stringMultiValueMap.add("client_secret", "TekE%dAISMCvwk7V");
        stringMultiValueMap.add("grant_type", "client_credentials");
        String tokenUrl = "https://identityserver:44310/connect/token";
        String clientRg = HttpClient.clientRg(tokenUrl, HttpMethod.POST, stringMultiValueMap);
        JSONObject jsonObject = JSONObject.parseObject(clientRg);
        String token = jsonObject.getString("access_token");
        System.out.println("token" + token);

        if(token != null){

//                for(int i = 1 ; i<=27; i++){
            Map<String, String> map1 = new HashMap<>();
            map1.put("dateFrom","2022-04-01");
//                    map1.put("pageSize",10000);

            //调用erp接口获取数据
            CloseableHttpClient client = HttpClients.createDefault();
            URIBuilder uriBuilder = new URIBuilder("http://10.18.3.10:30001/api/Epichust/GetAllIMOutSourceBills");
            HttpPost post = new HttpPost(uriBuilder.build());
            StringEntity myEntity = new StringEntity(JSON.toJSONString(map1), "UTF-8");// 构造请求数据
            post.setHeader("Content-Type", "application/json");
            post.addHeader("Authorization", "Bearer " + token);
            post.setEntity(myEntity);// 设置请求体
            String responseContent = null; // 响应内容
            CloseableHttpResponse response = null;
            try {
                response = client.execute(post);
                HttpEntity entity = response.getEntity();
                if (response.getStatusLine().getStatusCode() == 200) {
                    String content = EntityUtils.toString(entity, "UTF-8");
                    System.out.println(content);
//                            ItemResponseBO itemResponseBO = JSONArray.parseObject(content, ItemResponseBO.class);
//                            String it = itemResponseBO.getList();
//                            List<ItemErpBO> itemErpBOS = (List<ItemErpBO>) JSON
//                                    .parseArray(it, ItemErpBO.class);


                }
            } catch (Exception e) {
                e.printStackTrace();
            }  finally {
                try {
                    if (response != null)
                        response.close();

                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (client != null)
                            client.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
//                }


        }
    }

}
